//
//  LBAdaptiveThresholdFilter.mm
//  OpenGLGame
//
//  Created by Nguyen Cong Huy on 11/28/12.
//  Copyright (c) 2012 UIT. All rights reserved.
//

#include <iostream>
#include "LBAdaptiveThresholdFilter.h"
#include "LBGreyscaleFilter.h"
#include "LBBoxBlurFilter.h"
#include "LBTwoInputFilter.h"
#include "LBGraphics.h"
#include "LBFramebuffer.h"
#include "LBUtils.h"
#include "LBTexture.h"

char adaptiveThresholdFragStr[] = ""
"precision highp float;  "
"varying highp vec2 vtexCoor;"
"varying highp vec2 vtexCoor2;"

"uniform sampler2D texture;"
"uniform sampler2D texture2; "

"float safeColorF(float color){"
"    if(color > 1.0) color = 1.0;"
"    else if(color < 0.0) color = 0.0;"
"    return color;"
"}"

"highp vec4 safeColor(vec4 color){"
"    color.r = safeColorF(color.r);"
"    color.g = safeColorF(color.g);"
"    color.b = safeColorF(color.b);"
"    return color;"
"}"

"void main()"
"{"
"    float blurredInput = texture2D(texture, vtexCoor).r;"
"    float localLuminance = texture2D(texture2, vtexCoor2).r;"
"    float thresholdResult = step(blurredInput - 0.05, localLuminance);"

"    gl_FragColor = vec4(thresholdResult, thresholdResult, thresholdResult, 1.0);"
"}";

LBAdaptiveThresholdFilter::LBAdaptiveThresholdFilter(){
    luminanceFilter = new LBGreyscaleFilter();
    localLuminanceFilter = new LBGreyscaleFilter();
    boxBlurFilter = new LBBoxBlurFilter();
    setBlurSize(0.7);
    adaptiveFilter = new LBTwoInputFilter();
    adaptiveFilter->init(0, adaptiveThresholdFragStr);
}

LBAdaptiveThresholdFilter::~LBAdaptiveThresholdFilter(){
    DELETE_SAFELY(luminanceFilter);
    DELETE_SAFELY(localLuminanceFilter);
    DELETE_SAFELY(boxBlurFilter);
    DELETE_SAFELY(adaptiveFilter);
}

void LBAdaptiveThresholdFilter::setBlurSize(float blurSize){
    this->blurSize = blurSize;
    boxBlurFilter->setBlurSize(blurSize);
}

void LBAdaptiveThresholdFilter::render(){
    if(texture == 0){
        printf("Please setTexture() before\n");
        return;
    }
    luminanceFilter->setLocationAndScale(0, 0, 1.0, 1.0);
    luminanceFilter->render();
    
    localLuminanceFilter->setLocationAndScale(0, 0, 1.0, 1.0);
    localLuminanceFilter->render();
    
    
    adaptiveFilter->setTexture(boxBlurFilter->getOutputTexture());
    adaptiveFilter->setTexture2(localLuminanceFilter->getOutputTexture());
    adaptiveFilter->setLocationAndScale(0, 0, 1.0, 1.0);
    adaptiveFilter->render();
    
    /*LBTexture* tex = adaptiveFilter->getOutputTexture();
    LBGraphics::getInstance()->renderToScreen();
    tex->render();*/
    
    fbo->beginRenderToTexture();
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    

    adaptiveFilter->getOutputTexture()->renderUseDefaultProgram();
    
    if(targetFilter != 0)targetFilter->render();
}

void LBAdaptiveThresholdFilter::setTexture(LBTexture* texture){
    this->texture = texture;
    DELETE_SAFELY(outputTexture);
    outputTexture = new LBTexture(texture->getWidth(), texture->getHeight());
    DELETE_SAFELY(fbo);
    fbo = new LBFramebuffer(outputTexture);
    
    luminanceFilter->setTexture(texture);
    luminanceFilter->addTarget(boxBlurFilter);
    localLuminanceFilter->setTexture(texture);
    
    if(targetFilter != 0){
        targetFilter->setTexture(outputTexture);
    }
}